package com.itheima.jdk;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
jdk动态代理实现
* */
public class DemoJdkProxy {
    public static void main(String[] args) {
        //1.创建目标对象
        UserDaoImpl userDao = new UserDaoImpl();
        //2.创建代理对象
        /*
        * Jdk动态代理:基于接口
        * 涉及到的类:Proxy
        * 涉及的方法:newProxyInstance(param1,param2,param3)
        *参数:
        * param1:目标对象的类加载器(固定写法)
        * param2:目标对象实现的接口(固定写法)
        * param3:代理处理,需要程序自己手动实现
        *
        * com.sun.proxy.$Proxy0 cannot be cast to com.itheima.dao.impl.UserDaoImpl
        * */
        UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
            /*
             * @param proxy      代理对象(如果不指定目标对象,则此代理对象为null)
             * @param method     执行的方法对象
             * @param args       执行方法对象的参数列表
             * @return           返回执行的方法对象的返回值,如果执行的方法是void,则此返回值可以为null
             * @throws Throwable
             * */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object obj = null;
                if ("save".equals(method.getName())){
                   return method.invoke(userDao, args);
                }else{
                    try {
                        System.out.println("前置增强");//在目标方法执行之前,称之为前置增强
                        obj = method.invoke(userDao, args);//执行userDao对象中带有args参数列表的method方法
                        System.out.println("后置增强");
                    } catch (Exception e) {
                        System.out.println("异常增强");
                    } finally {
                        System.out.println("最终增强");
                    }
                }
                return obj;
            }
        });
        proxy.save();
        String speak = proxy.speak();
        System.out.println(speak);
    }
}
